from types import SimpleNamespace

from ultralytics.cfg import cfg2dict, check_dict_alignment, check_cfg
from ultralytics.utils import yaml_load, IterableSimpleNamespace, LOGGER
from pathlib import Path
from typing import Dict, List, Union
import yaml

FILE = Path(__file__).resolve()
ROOT = FILE.parents[1]
DEFAULT_CFG_PATH = ROOT / "cfg/default.yaml"

# Default configuration
DEFAULT_CFG_DICT = yaml_load(DEFAULT_CFG_PATH)
for k, v in DEFAULT_CFG_DICT.items():
    if isinstance(v, str) and v.lower() == "none":
        DEFAULT_CFG_DICT[k] = None
DEFAULT_CFG_KEYS = DEFAULT_CFG_DICT.keys()
DEFAULT_CFG = IterableSimpleNamespace(**DEFAULT_CFG_DICT)


def get_cfg(cfg: Union[str, Path, Dict, SimpleNamespace] = DEFAULT_CFG_DICT, overrides: Dict = None):
    cfg = cfg2dict(cfg)
    # Merge overrides
    if overrides:
        overrides = cfg2dict(overrides)
        if "save_dir" not in cfg:
            overrides.pop("save_dir", None)  # special override keys to ignore
        check_dict_alignment(cfg, overrides)
        cfg = {**cfg, **overrides}  # merge cfg and overrides dicts (prefer overrides)

    # Special handling for numeric project/name
    for k in "project", "name":
        if k in cfg and isinstance(cfg[k], (int, float)):
            cfg[k] = str(cfg[k])
    if cfg.get("name") == "model":  # assign model to 'name' arg
        cfg["name"] = cfg.get("model", "").split(".")[0]
        LOGGER.warning(f"WARNING ⚠️ 'name=model' automatically updated to 'name={cfg['name']}'.")

    # Type and Value checks
    check_cfg(cfg)

    # Return instance
    return IterableSimpleNamespace(**cfg)


def get_model_path(args):
    if getattr(args, "model_path", None):
        model_path = args.model_path
    else:
        model_path = ROOT / "weights/"
    print(model_path)
    return str(model_path)


def get_folder_path(args):
    if getattr(args, "folder_path", None):
        folder_path = args.folder_path
    else:
        folder_path = ROOT / "test/orig"
    return str(folder_path)


def get_file_path(args):
    if getattr(args, "file_path", None):
        file_path = args.file_path
    else:
        file_path = ROOT / "test/orig/bus"
    return str(file_path)


# 更新yaml文件
def update_yaml(path, key, value):
    with open(path, "r", encoding="utf-8") as f:
        data = yaml.load(f, Loader=yaml.FullLoader)  #读取文件数据
    # 修改读取的数据（k存在就修改对应值，k不存在就新增一组键值对）
    data[key] = value
    with open(path, "w", encoding="utf-8") as f:
        yaml.dump(data, f)
